<!-- 该文件是无缝轮播生效的，只是比较难以理解 -->
<template>
  <div class="rank-container">
    <div class="rank-header">
      <div class="rank-col rank-col-num">排名</div>
      <div class="rank-col rank-col-name">设备名称</div>
      <div class="rank-col rank-col-value">{{ type === 'power' ? '功率(kW)' : '电量(kWh)' }}</div>
    </div>

    <div class="rank-body">
      <div ref="listRef" class="rank-list" :style="{ transform: `translateY(${-scrollOffset}px)` }">
        <div
          v-for="(item, index) in displayList"
          :key="`${item.id}-${index}`"
          class="rank-item"
          :class="{ active: index % rankList.length < 3 }"
        >
          <div class="rank-col rank-col-num">
            <span class="rank-index">{{ (index % rankList.length) + 1 }}</span>
          </div>
          <div class="rank-col rank-col-name">{{ item.name }}</div>
          <div class="rank-col rank-col-value">{{ item.value }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'

const props = defineProps({
  type: {
    type: String,
    required: true
  },
  rankList: {
    type: Array,
    default: () => []
  }
})

const listRef = ref(null)
const scrollOffset = ref(0)
let timer = null

// 判断是否需要滚动
const shouldScroll = computed(() => {
  return props.rankList.length > 5
})

// 根据数据量决定显示列表（重复三次）
const displayList = computed(() => {
  return shouldScroll.value ? [...props.rankList, ...props.rankList] : props.rankList
})

// 平滑滚动到指定位置
const smoothScrollTo = (target) => {
  const start = scrollOffset.value
  const change = target - start
  const duration = 500 // 动画持续时间
  let startTime = null

  const animation = (currentTime) => {
    if (!startTime) startTime = currentTime
    const timeElapsed = currentTime - startTime
    const progress = Math.min(timeElapsed / duration, 1)

    // 使用 easeInOutQuad 缓动函数
    const easeProgress = progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2

    scrollOffset.value = start + change * easeProgress

    if (timeElapsed < duration) {
      requestAnimationFrame(animation)
    } else {
      // 如果滚动到了第二组数据的末尾，立即重置到第一组对应位置
      if (scrollOffset.value >= props.rankList.length * 45) {
        scrollOffset.value = scrollOffset.value % (props.rankList.length * 45)
      }
    }
  }

  requestAnimationFrame(animation)
}

// 开始轮播
const startScroll = () => {
  if (!shouldScroll.value) return
  stopScroll()

  timer = setInterval(() => {
    const nextOffset = scrollOffset.value + 45
    smoothScrollTo(nextOffset)
  }, 3000)
}

// 停止轮播
const stopScroll = () => {
  if (timer) {
    clearInterval(timer)
    timer = null
  }
}

// 监听数据变化
watch(
  () => props.rankList,
  () => {
    scrollOffset.value = 0
    startScroll()
  },
  { deep: true }
)

onMounted(() => {
  startScroll()
})

onBeforeUnmount(() => {
  stopScroll()
})
</script>

<style scoped>
.rank-container {
  width: 100%;
  height: 100%;
  color: #fff;
}

.rank-header {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 15px;
  background: rgba(255, 255, 255, 0.1);
  margin-bottom: 5px;
}

.rank-body {
  height: calc(100% - 45px);
  overflow: hidden;
}

.rank-list {
  will-change: transform;
}

.rank-item {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 15px;
  background: rgba(255, 255, 255, 0.05);
  margin-bottom: 5px;
}

.rank-item.active {
  background: linear-gradient(90deg, rgba(0, 183, 255, 0.2), transparent);
}

.rank-col {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rank-col-num {
  width: 60px;
}

.rank-col-name {
  flex: 1;
  padding: 0 10px;
}

.rank-col-value {
  width: 100px;
  text-align: right;
}

.rank-index {
  display: inline-block;
  width: 24px;
  height: 24px;
  line-height: 24px;
  text-align: center;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
}

.rank-item.active .rank-index {
  background: #00b7ff;
}
</style>
